import 'dart:collection';
import 'dart:ffi';

import 'package:device_calendar/device_calendar.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:intl/intl.dart';
import 'package:photo_frame/dialog/edit_member_dialog.dart';
import 'package:photo_frame/dialog/new_schedule_dialog.dart';
import 'package:photo_frame/dialog/new_schedule_successful_dialog.dart';
import 'package:photo_frame/net/http_manager.dart';
import 'package:photo_frame/net/model/event_dto.dart';
import 'package:photo_frame/net/model/frame_info_model.dart';
import 'package:photo_frame/net/model/member_model.dart';
import 'package:photo_frame/pages/device/device_list_page.dart';
import 'package:photo_frame/provider/frames_provider.dart';
import 'package:photo_frame/provider/schedule_provider.dart';
import 'package:photo_frame/provider/users_provider.dart';
import 'package:photo_frame/router/router_context.dart';
import 'package:photo_frame/user/user_manager.dart';
import 'package:photo_frame/utils/a_logger.dart';
import 'package:photo_frame/utils/app_const.dart';
import 'package:photo_frame/utils/calendar_helper.dart';
import 'package:photo_frame/utils/calendar_helper.dart';
import 'package:photo_frame/utils/color_util.dart';
import 'package:photo_frame/utils/localization_util.dart';
import 'package:photo_frame/utils/time_util.dart';
import 'package:photo_frame/widgets/app_bar_widget.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:table_calendar/table_calendar.dart';

class CalendarPage extends StatefulWidget {
  const CalendarPage({super.key});

  @override
  State<CalendarPage> createState() => _CalendarPageState();
}

// showDialog(
//     context: context, builder: (_) => NewScheduleSuccessfulDialog());
class _CalendarPageState extends State<CalendarPage>
    with AutomaticKeepAliveClientMixin {
  CalendarViewModel vm = CalendarViewModel();
  late PageController _pageController;

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    vm.init(context);
  }

  @override
  void dispose() {
    super.dispose();
    vm.dispose();
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return ChangeNotifierProvider<CalendarViewModel>(
        create: (_) => vm,
        child: Scaffold(
          appBar: commonAppBar(
            null,
            titleWidget: _titleWidget(),
            leading: _leadingWidget(),
            actions: [_actionWidget()],
          ),
          floatingActionButton: CupertinoButton(
            padding: EdgeInsets.zero,
            onPressed: () {
              if (vm._selectedFrameInfoModel == null) {
                Fluttertoast.showToast(
                    msg: AppLocalizationsWrapper.instance
                        .unwrapNoCtx()
                        .pleaseBindAFrameFirst);
                return;
              }
              ALogger.e("_showNewScheduleDialog");
              var nowDateTime = DateTime.now();
              var localSelectedDateTime = vm.selectedDate.toLocal();
              _showNewScheduleDialog(
                  startDateTime: nowDateTime.copyWith(
                      year: localSelectedDateTime.year,
                      month: localSelectedDateTime.month,
                      day: localSelectedDateTime.day));
            },
            child: Container(
              width: 50,
              height: 50,
              decoration: BoxDecoration(
                shape: BoxShape.circle,
                gradient: LinearGradient(
                  colors: [Color(0xff4048EF), Color(0xff5A7BEF)],
                  begin: Alignment.topLeft,
                  end: Alignment.bottomRight,
                ),
              ),
              child: Center(
                child: Image.asset(
                  "images/pic_add.png",
                  width: 24,
                  height: 24,
                  color: Colors.white,
                ),
              ),
            ),
          ),
          body: SafeArea(
            child: Column(
              children: [
                _weekWidget(),
                Expanded(
                  child: RefreshIndicator(
                    color: Color(0xff3F74EF),
                    key: vm._refreshIndicatorStateKey,
                    onRefresh: () {
                      return vm.realFetchEventsBySelectDate();
                    },
                    child: CustomScrollView(
                      slivers: [
                        SliverPadding(padding: EdgeInsets.only(top: 8)),
                        _memberWidget(),
                        SliverPadding(padding: EdgeInsets.only(top: 13.5)),
                        _todoListWidget(),
                      ],
                    ),
                  ),
                ),
              ],
            ),
          ),
        ));
  }

  _titleWidget() {
    return Selector<CalendarViewModel, DateTime?>(
        builder: (BuildContext context, value, Widget? child) => Text(
              value == null
                  ? ""
                  : DateFormat.yMMM(
                          Localizations.localeOf(context).languageCode)
                      .format(value),
              style: const TextStyle(
                fontSize: 18,
                color: Color(0xff333333),
                fontWeight: FontWeight.bold,
              ),
            ),
        selector: (_, v) => v.selectedYYMMDate,
        shouldRebuild: (n1, n2) => n1 != n2);
  }

  _leadingWidget() {
    return Padding(
      padding: const EdgeInsets.only(left: 18, top: 10, bottom: 10, right: 2),
      child: CupertinoButton(
        padding: EdgeInsets.zero,
        onPressed: () async {
          await ARouter.instance.pagePush("/selectFrame",
              arguments: {"source": SelectFrameSource.CALENDAR}).then((e) {
            if (e != null) {
              vm.selectFrame(context, e);
            }
          });
        },
        child: Row(
          children: [
            Image.asset("images/icon_frame_switch.png", width: 24, height: 20),
            SizedBox(width: 5),
            Selector<CalendarViewModel, String?>(
              builder: (BuildContext context, value, Widget? child) => Text(
                value ?? "",
                style: TextStyle(color: Color(0xff333333), fontSize: 10),
                maxLines: 1,
                overflow: TextOverflow.ellipsis,
              ),
              shouldRebuild: (n1, n2) => n1 != n2,
              selector: (_, vm) => vm._selectedFrameInfoModel?.name ?? "",
            )
          ],
        ),
      ),
    );
  }

  _actionWidget() {
    return CupertinoButton(
      padding: EdgeInsets.zero,
      onPressed: () {
        ARouter.instance.pagePush("/importSchedule",
            arguments: {"frameId": vm._selectedFrameInfoModel?.frame_id});
      },
      child: Container(
        height: 34,
        margin: EdgeInsets.only(right: 7.5),
        decoration: BoxDecoration(
          border: Border.all(
            color: Color(0xff3F74EF),
            width: 1,
          ),
          borderRadius: BorderRadius.circular(22),
        ),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            SizedBox(width: 8),
            Icon(
              Icons.cached,
              color: Color(0xff3F74EF),
              size: 22,
            ),
            SizedBox(width: 7),
            Text(
              AppLocalizationsWrapper.instance.unwrap(context).import,
              style: TextStyle(
                  color: Color(0xff3F74EF),
                  fontSize: 14,
                  fontWeight: FontWeight.bold),
            ),
            SizedBox(width: 8),
          ],
        ),
      ),
    );
  }

  _weekWidget() {
    return Container(
      padding: EdgeInsets.only(top: 10, bottom: 10),
      color: Colors.white,
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          CupertinoButton(
            padding: EdgeInsets.zero,
            onPressed: () {
              _pageController.previousPage(
                duration: Duration(milliseconds: 300),
                curve: Curves.easeOut,
              );
            },
            child: Padding(
              padding: const EdgeInsets.only(right: 8.0),
              child: Container(
                width: 11,
                height: 60,
                alignment: Alignment.center,
                color: Color(0xffF5F5F7),
                child: Image.asset(
                  "images/icon_arrow_left.png",
                  width: 5,
                  height: 14,
                ),
              ),
            ),
          ),
          Expanded(
            child: Selector<CalendarViewModel, DateTime>(
              builder: (BuildContext context, DateTime value, Widget? child) {
                return TableCalendar(
                  onCalendarCreated: (controller) {
                    _pageController = controller;
                  },
                  onPageChanged: (DateTime focusedDay) {
                    vm.selectYYMMDate(focusedDay);
                  },
                  headerVisible: false,
                  calendarFormat: CalendarFormat.week,
                  firstDay: DateTime.utc(2024, 3, 30),
                  lastDay: DateTime.utc(2050, 12, 31),
                  focusedDay: value,
                  daysOfWeekHeight: 32,
                  rowHeight: 32,
                  onDaySelected: (d1, d2) {
                    vm.selectDate(d1);
                  },
                  calendarBuilders: CalendarBuilders(
                    defaultBuilder: _weekDefaultBuilder,
                    outsideBuilder: _weekDefaultBuilder,
                    dowBuilder: (BuildContext context, DateTime day) {
                      final selected = isSameDay(day, vm.selectedDate);
                      final week = DateFormat.E(
                              Localizations.localeOf(context).languageCode)
                          .format(day)
                          .replaceAll("周", '');
                      return CupertinoButton(
                        padding: EdgeInsets.zero,
                        onPressed: () {
                          if (!selected) {
                            vm.selectDate(day);
                          }
                        },
                        child: Container(
                            decoration: BoxDecoration(
                              color: Color(selected ? 0xff3F74EF : 0x00000000),
                              borderRadius: BorderRadius.vertical(
                                  top: Radius.circular(selected ? 4 : 0)),
                            ),
                            child: Center(
                              child: Text(
                                week,
                                style: TextStyle(
                                    color: selected
                                        ? Colors.white
                                        : Color(0xff999999),
                                    fontSize: 14),
                              ),
                            )),
                      );
                    },
                  ),
                  selectedDayPredicate: (DateTime day) {
                    return isSameDay(day, vm.selectedDate);
                  },
                  calendarStyle: CalendarStyle(
                    isTodayHighlighted: false,
                    canMarkersOverflow: false,
                    outsideDaysVisible: false,
                    markersAutoAligned: false,
                    cellMargin: EdgeInsets.zero,
                    selectedTextStyle: TextStyle(color: Colors.white),
                    defaultTextStyle: TextStyle(color: Color(0xff333333)),
                    defaultDecoration: BoxDecoration(
                      color: Colors.transparent,
                      borderRadius: BorderRadius.circular(5),
                    ),
                    selectedDecoration: BoxDecoration(
                      color: const Color(0xff3F74EF),
                      shape: BoxShape.rectangle,
                      borderRadius: BorderRadius.vertical(
                        bottom: Radius.circular(4),
                      ),
                    ),
                  ),
                );
              },
              selector: (_, v) => v.selectedDate,
              shouldRebuild: (n1, n2) => n1 != n2,
            ),
          ),
          CupertinoButton(
            padding: EdgeInsets.zero,
            onPressed: () {
              _pageController.nextPage(
                duration: Duration(milliseconds: 300),
                curve: Curves.easeOut,
              );
            },
            child: Padding(
              padding: const EdgeInsets.only(left: 8.0),
              child: Container(
                width: 11,
                height: 60,
                alignment: Alignment.center,
                color: Color(0xffF5F5F7),
                child: Image.asset(
                  "images/icon_arrow_right.png",
                  width: 5,
                  height: 14,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }

  Widget _weekDefaultBuilder(
      BuildContext context, DateTime day, DateTime focusedDay) {
    return Center(
      child: Text(day.day.toString(),
          style: TextStyle(color: Color(0xff000000), fontSize: 16)),
    );
  }

  Widget _memberWidget() {
    final memberItemW =
        ((MediaQuery.of(context).size.width - 25 - (4 - 1) * 10) / 4)
            .roundToDouble();
    final memberItemH = memberItemW / 0.8;
    return SliverToBoxAdapter(
      child: SizedBox(
        height: memberItemH,
        child: Selector<CalendarViewModel, List<MemberCompletionItem>?>(
          builder: (BuildContext context, value, Widget? child) {
            return ListView.separated(
              scrollDirection: Axis.horizontal,
              itemCount: (value?.length ?? 0) + 1,
              itemBuilder: (context, index) {
                final last = index == ((value?.length ?? 0) + 1) - 1;
                return CupertinoButton(
                  padding: EdgeInsets.zero,
                  onPressed: () async {
                    if (vm._selectedFrameInfoModel == null) {
                      Fluttertoast.showToast(
                          msg: AppLocalizationsWrapper.instance
                              .unwrapNoCtx()
                              .pleaseBindAFrameFirst);
                      return;
                    }
                    await ARouter.instance.pagePush("/memberListPage",
                        arguments: {
                          'frameId': vm._selectedFrameInfoModel?.frame_id
                        });
                  },
                  child: Padding(
                      padding: EdgeInsets.only(
                          left: index == 0 ? 12.5 : 0, right: last ? 12.5 : 0),
                      child: last
                          ? _addMemberItemWidget(context, index,
                              vm._selectedFrameInfoModel?.frame_id, memberItemW)
                          : _memberItemWidget(context, index, memberItemW)),
                );
              },
              separatorBuilder: (context, index) => VerticalDivider(
                width: 10,
                color: Colors.transparent,
              ),
            );
          },
          selector: (_, v) => v.memberCompletionList,
        ),
      ),
    );
  }

  Widget _memberItemWidget(BuildContext context, int index, double width) {
    final item = vm.memberCompletionList![index];
    return Container(
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(12),
      ),
      width: width,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Container(
            alignment: Alignment.center,
            decoration: BoxDecoration(
              color: Color(item.color ?? DEFAULT_COLOR.value),
              shape: BoxShape.circle,
            ),
            width: 33,
            height: 33,
            child: Text(
              item.name?.isNotEmpty == true ? item.name!.substring(0, 1) : "",
              style: TextStyle(
                  color: Colors.white,
                  fontSize: 15,
                  fontWeight: FontWeight.bold),
            ),
          ),
          SizedBox(height: 5),
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 4),
            child: Text(
              item.name ?? "",
              maxLines: 1,
              overflow: TextOverflow.ellipsis,
              style: TextStyle(
                  color: Color(0xff555555),
                  fontSize: 14,
                  fontWeight: FontWeight.bold),
            ),
          ),
          SizedBox(height: 6),
          Text(
            "${item.progress ?? ""}  ${AppLocalizationsWrapper.instance.unwrap(context).completed}",
            style: TextStyle(color: Color(0xff999999), fontSize: 12),
            textAlign: TextAlign.center,
          ),
        ],
      ),
    );
  }

  Widget _addMemberItemWidget(
      BuildContext context, int index, String? frameId, double width) {
    return SizedBox(
      width: width,
      child: Opacity(
        opacity: 0.5,
        child: Container(
          decoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.circular(12),
          ),
          child: Center(
            child: Image.asset(
              "images/pic_add.png",
              width: 35,
              height: 35,
              fit: BoxFit.cover,
            ),
          ),
        ),
      ),
    );
  }

  Widget _todoListWidget() {
    return Selector<CalendarViewModel, List<CalendarItem>?>(
      builder: (context, value, child) => (value?.length ?? 0) > 0
          ? _calendarListWidget(value)
          : _calendarListEmptyWidget(),
      selector: (_, v) => v.calendarList,
      shouldRebuild: (n1, n2) => n1 != n2,
    );
  }

  Widget _calendarListWidget(List<CalendarItem>? list) {
    return SliverList.separated(
      itemCount: list?.length ?? 0,
      itemBuilder: (context, index) {
        final item = list![index];
        return item.itemType == 1
            ? Padding(
                padding: EdgeInsets.only(
                    left: 13.5, top: index == 0 ? 0 : 7, bottom: 7),
                child: Text(item.itemTitle,
                    style: TextStyle(
                        color: Color(0xff555555),
                        fontSize: 14,
                        fontWeight: FontWeight.bold)),
              )
            : Padding(
                padding: EdgeInsets.only(
                    bottom: (index == list.length - 1) ? 14 : 0),
                child: _calendarItemWidget(context, index, list[index]),
              );
      },
      separatorBuilder: (BuildContext context, int index) =>
          Divider(height: 5, color: Colors.transparent),
    );
  }

  Widget _calendarListEmptyWidget() {
    return SliverToBoxAdapter(
      child: Column(
        children: [
          SizedBox(height: 77.5),
          Image.asset("images/icon_calendar_list_empty.png",
              width: 100, height: 100),
          SizedBox(height: 9),
          Text(
              AppLocalizationsWrapper.instance
                  .unwrapNoCtx()
                  .calendarListEmptyTitle,
              style: TextStyle(
                  color: Color(0xff666666),
                  fontSize: 16,
                  fontWeight: FontWeight.bold)),
          Text(
            AppLocalizationsWrapper.instance
                .unwrapNoCtx()
                .calendarListEmptySubtitle,
            style: TextStyle(color: Color(0xff999999), fontSize: 12),
          ),
        ],
      ),
    );
  }

  Widget _calendarItemWidget(
      BuildContext context, int index, CalendarItem item) {
    var event = item.eventDTO;
    var finish = event?.todayFinish == 1;
    return CupertinoButton(
      padding: EdgeInsets.zero,
      onPressed: () {
        ALogger.e("_calendarItemWidget event?.accountName ${event}");
        if (!finish) {
          _showNewScheduleDialog(event: event);
        }
      },
      child: Container(
        height: 66,
        margin: EdgeInsets.symmetric(horizontal: 11.5),
        child: Card(
          color: Colors.white,
          shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(2)),
          child: Row(
            children: [
              Container(
                width: 4,
                color: Color(finish ? 0xffCECECE : item.color ?? 0xff4B90FF),
              ),
              SizedBox(width: 10),
              CupertinoButton(
                padding: EdgeInsets.zero,
                onPressed: () {
                  // if (event?.isFotocube() == true) {
                  // event!.finish = 1;
                  if (event == null) return;
                  EasyLoading.show();
                  vm._scheduleViewModel
                      .finishEventWithTimestamp(
                          event, vm.selectedDate.millisecondsSinceEpoch)
                      .catchError((_) {
                    EasyLoading.dismiss();
                  }).whenComplete(() {
                    showDialog(
                        context: context,
                        builder: (_) => NewScheduleSuccessfulDialog());
                    EasyLoading.dismiss();
                  });
                  // }
                },
                child: Image.asset(
                  finish
                      ? "images/icon_completed.png"
                      : "images/icon_agree_circle.png",
                  width: 22,
                  height: 22,
                ),
              ),
              SizedBox(width: 14.5),
              Expanded(
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      item.title ?? "",
                      style: TextStyle(
                        color: Color(finish ? 0xff999999 : 0xff000000),
                        fontSize: 14,
                        fontWeight: FontWeight.bold,
                      ),
                      maxLines: 1,
                      overflow: TextOverflow.ellipsis,
                    ),
                    Text(
                      item.subtitle ?? "",
                      style: TextStyle(
                        color: Color(finish
                            ? 0xff999999
                            : int.tryParse(
                                    item.subtitleColor ?? "0xff999999") ??
                                0xff999999),
                        fontSize: 12,
                      ),
                    ),
                  ],
                ),
              ),
              Opacity(
                opacity: finish ? 0.5 : 1,
                child: Container(
                  alignment: Alignment.center,
                  decoration: BoxDecoration(
                    color: Color(item.color ?? 0xff4B90FF).withOpacity(1),
                    shape: BoxShape.circle,
                  ),
                  width: 33,
                  height: 33,
                  child: Text(
                    item.name?.isNotEmpty == true
                        ? item.name!.substring(0, 1)
                        : "",
                    style: TextStyle(
                        color: Colors.white,
                        fontSize: 11,
                        fontWeight: FontWeight.bold),
                  ),
                ),
              ),
              SizedBox(width: 5),
              // Opacity(
              //   opacity: finish ? 0.5 : 1,
              //   child: Text(
              //     (item.name?.length ?? 0) > 5
              //         ? "${item.name}..."
              //         : item.name ?? "",
              //     style: TextStyle(
              //         color: Color(0xff555555),
              //         fontSize: 14,
              //         overflow: TextOverflow.ellipsis,
              //         fontWeight: FontWeight.bold),
              //   ),
              // ),
              SizedBox(width: 29.5),
            ],
          ),
        ),
      ),
    );
  }

  _showNewScheduleDialog({EventDTO? event, DateTime? startDateTime}) {
    showDialog(
        context: context,
        builder: (BuildContext context) => NewScheduleDialog(
            vm._selectedFrameInfoModel?.frame_id, vm._memList ?? [],
            event: event, startDateTime: startDateTime)).then((e) {});
  }

  @override
  bool get wantKeepAlive => true;
}

class CalendarViewModel extends ChangeNotifier {
  late ScheduleViewModel _scheduleViewModel;
  late FramesViewModel _framesViewModel;
  late UsersViewModel _usersViewModel;
  FrameInfoModel? _selectedFrameInfoModel;
  DateTime _selectedDate = DateTime.now().toUtc();
  GlobalKey<RefreshIndicatorState> _refreshIndicatorStateKey = GlobalKey();

  DateTime get selectedDate => _selectedDate;

  late DateTime selectedYYMMDate = _selectedDate;

  List<MemberModel>? _memList;

  List<MemberCompletionItem>? memberCompletionList;

  List<CalendarItem>? calendarList;

  late VoidCallback framesCallback;
  late VoidCallback usersCallback;
  late VoidCallback eventCallback;

  init(BuildContext context) {
    _framesViewModel = context.read<FramesViewModel>();
    _framesViewModel.addListener(framesCallback = () {
      ALogger.e("framesCallback find:enter");
      final idx = _framesViewModel.frames?.indexWhere(
              (e) => e.frame_id == _selectedFrameInfoModel?.frame_id) ??
          -1;
      if (idx == -1) {
        _selectedFrameInfoModel = null;
        _memList = null;
        memberCompletionList = null;
        calendarList = null;
        notifyListeners();
        ALogger.e("framesCallback reset");
      }

      if (_selectedFrameInfoModel == null &&
          _framesViewModel.frames?.isNotEmpty == true) {
        SharedPreferences.getInstance().then((e) {
          var lastSelectedFrameId = e.getString("selectedFrameId");
          _selectedFrameInfoModel = _framesViewModel.frames!.firstWhere(
              (e) => e.frame_id == lastSelectedFrameId,
              orElse: () => _framesViewModel.frames![0]);
          _usersViewModel.fetch(_selectedFrameInfoModel?.frame_id ?? "");
        });
      }
      print("onFramesSyncComplete ${_framesViewModel.frames?.length}");
    });

    ALogger.e(
        "CalendarViewModel init-_framesViewModel.frames?: ${_framesViewModel.hashCode}  ${_framesViewModel.frames?.length} ");

    _usersViewModel = context.read<UsersViewModel>();
    _usersViewModel.addListener(usersCallback = () {
      _memList = _usersViewModel.members
          .filterByFrameId(_selectedFrameInfoModel?.frame_id ?? "");
      fetchEventsBySelectDate();
      notifyListeners();
      print("onUsersSyncComplete ${_memList?.length}");
    });

    _scheduleViewModel = context.read<ScheduleViewModel>();
    _scheduleViewModel.addListener(eventCallback = () {
      _dealEvents(_memList?.toList() ?? List.empty()).then((_) {
        notifyListeners();
        print("onEventSyncComplete ${_scheduleViewModel.allEvent.length}");
      });
    });

    if (_framesViewModel.frames?.isNotEmpty == true) {
      ALogger.e("CalendarViewModel init: ");
      framesCallback();
    } else {
      _framesViewModel.fetch();
    }
  }

  @override
  void dispose() {
    super.dispose();
    _scheduleViewModel.removeListener(eventCallback);
    _framesViewModel.removeListener(framesCallback);
    _usersViewModel.removeListener(usersCallback);
  }

  selectYYMMDate(DateTime date) {
    if (date.month == selectedYYMMDate.month) {
      return;
    }
    selectedYYMMDate = date;
    notifyListeners();
  }

  selectFrame(BuildContext context, FrameInfoModel frameInfoModel) {
    SharedPreferences.getInstance().then(
        (e) => {e.setString("selectedFrameId", frameInfoModel.frame_id ?? "")});
    _selectedFrameInfoModel = frameInfoModel;
    notifyListeners();
    _usersViewModel.fetch(frameInfoModel.frame_id ?? "");
  }

  selectDate(DateTime date) async {
    _selectedDate = date;
    notifyListeners();
    fetchEventsBySelectDate();
    // fetchEvents(_memList?.toList() ?? List.empty()).then((_) {
    //   notifyListeners();
    // });
  }

  fetchEventsBySelectDate() {
    _refreshIndicatorStateKey.currentState?.show();
  }

  realFetchEventsBySelectDate() async {
    try {
      await _usersViewModel.fetch(_selectedFrameInfoModel?.frame_id ?? "", notify: false);
      _memList = _usersViewModel.members
          .filterByFrameId(_selectedFrameInfoModel?.frame_id ?? "");
      ALogger.e("user lsize :  ${_memList?.length??0}" ,);
      notifyListeners();
    } catch (e) {
      ALogger.e(e);
    }
    return _scheduleViewModel.fetchEvents(
        frameId: _selectedFrameInfoModel?.frame_id,
        from: _selectedDate.startOfDay().toUtc().millisecondsSinceEpoch,
        to: _selectedDate.endOfDay().toUtc().millisecondsSinceEpoch);
  }

  Future<void> _dealEvents(List<MemberModel> memberList) async {
    ALogger.e("dealEvents-enter : ${memberList.map((e) => e.id)}");

    if (memberList.isEmpty) {
      memberCompletionList = [];
      calendarList = [];
      return;
    }
    // ALogger.i("dealEvents ${_selectedDate}");
    var queryEvent = await _scheduleViewModel.queryEvent(
      _selectedFrameInfoModel?.frame_id,
      _selectedDate,
      _selectedDate,
    );
    queryEvent ??= [];
    if (queryEvent.isNotEmpty != true) {
      memberCompletionList = memberList
          .map((e) => MemberCompletionItem()
            ..name = e.name
            ..color = e.fixedColor
            ..progress = "")
          .toList();
      calendarList = [];
      return;
    }
    // memberCompletionList
    Map<int, List<EventDTO>> groupRes =
        await groupEventsByAttendees(queryEvent);

    memberCompletionList = memberList.map((e) {
      var memberCompletionItem = MemberCompletionItem();
      memberCompletionItem
        ..name = e.name
        ..color = e.fixedColor;
      var events = groupRes[e.id];
      if (events?.isNotEmpty == true) {
        var count = events!.where((e) => e.todayFinish == 1).length;
        memberCompletionItem.progress = "$count/${events.length}";
      }
      return memberCompletionItem;
    }).toList();
    calendarList = await processCalendarItems(groupRes, memberList);

    final hasTodo = calendarList?.lastIndexWhere((e) => e.finish != 1);
    if (hasTodo != -1) {
      calendarList?.insert(
          0,
          CalendarItem()
            ..itemType = 1
            ..itemTitle = AppLocalizationsWrapper.instance.unwrapNoCtx().todo);
    }
    final finishIdx = calendarList?.indexWhere((e) => e.finish == 1);
    if (finishIdx != -1) {
      calendarList?.insert(
          finishIdx!,
          CalendarItem()
            ..itemType = 1
            ..itemTitle =
                AppLocalizationsWrapper.instance.unwrapNoCtx().completed);
    }
  }

  Future<List<CalendarItem>> processCalendarItems(
      Map<int, List<EventDTO>> groupRes, List<MemberModel> memberList) async {
    List<CalendarItem> calendarList = [];

    await Future.forEach(groupRes.entries, (entry) async {
      List<Future<CalendarItem>> items = await entry.value.map((e) async {
        var memberModel =
            memberList.where((m) => m.id == entry.key).firstOrNull;
        return CalendarItem()
          ..eventDTO = e
          ..finish = e.todayFinish
          ..title = e.title
          ..subtitle = parseSubtitle(e).toString()
          ..name = memberModel?.name ?? UserManager.instance.getName()
          ..color = memberModel?.color ?? DEFAULT_COLOR.value;
      }).toList();

      List<CalendarItem> resolvedItems = await Future.wait(items);
      calendarList.addAll(resolvedItems);
    });

    calendarList.sort((a1, a2) {
      int statusComparison = (a1.eventDTO?.todayFinish ?? 0)
          .compareTo(a2.eventDTO?.todayFinish ?? 0);
      if (statusComparison != 0) {
        return statusComparison;
      }
      return (a2.eventDTO?.etag ?? 0).compareTo(a1.eventDTO?.etag ?? 0);
    });
    return calendarList;
  }

  StringBuffer parseSubtitle(EventDTO e) {
    StringBuffer sb = StringBuffer();
    if (e.allDay == 1) {
      sb.write(AppLocalizationsWrapper.instance
          .unwrapNoCtx()
          .newScheduleDialogAllDay);
    } else {
      // ALogger.e(
      //     "from :${e.dtstart} ${DateFormat('HH:mm').format(DateTime.fromMillisecondsSinceEpoch(e.dtstart ?? 0, isUtc: true).toLocal())}");
      sb.write(DateFormat('HH:mm').format(
          DateTime.fromMillisecondsSinceEpoch(e.dtstart ?? 0, isUtc: true)
              .toLocal()));
      sb.write(" ");
      sb.write(DateFormat('HH:mm').format(
          DateTime.fromMillisecondsSinceEpoch(e.dtend ?? 0, isUtc: true)
              .toLocal()));
    }
    sb.write("  ");
    try {
      var rule = e.toRecurrenceRule();
      // ALogger.e("parseSubtitle : rule=${rule?.recurrenceFrequency}");
      switch (rule?.recurrenceFrequency) {
        case RecurrenceFrequency.Daily:
          sb.write(AppLocalizationsWrapper.instance
              .unwrapNoCtx()
              .newScheduleDialogRepeatModeDay);
          break;
        case RecurrenceFrequency.Weekly:
          sb.write(AppLocalizationsWrapper.instance
              .unwrapNoCtx()
              .newScheduleDialogRepeatModeWeek);
          break;
        case RecurrenceFrequency.Monthly:
          sb.write(AppLocalizationsWrapper.instance
              .unwrapNoCtx()
              .newScheduleDialogRepeatModeMonth);
          break;
        case RecurrenceFrequency.Yearly:
          sb.write(AppLocalizationsWrapper.instance
              .unwrapNoCtx()
              .newScheduleDialogRepeatModeYear);
          break;
        default:
          sb.write(AppLocalizationsWrapper.instance
              .unwrapNoCtx()
              .newScheduleDialogRepeatModeNever);
      }
    } catch (e) {
      ALogger.e(e);
    }
    return sb;
  }

  Future<Map<int, List<EventDTO>>> groupEventsByAttendees(
      List<EventDTO> events) async {
    ALogger.i(
        "groupEventsByAttendees enter-start ${events.map((e) => e.attendees).toList()}");

    Map<int, List<EventDTO>> groupedEvents = {};
    HashSet<int> uids = HashSet<int>();

    try {
      await Future.forEach(events, (event) async {
        List<String> memberList = event.memberList;
        // if (event.memberList.isEmpty) {
        //
        // }
        List<String> trimmedMembers = memberList.map((e) => e.trim()).toList();
        List<int> parsedMembers = trimmedMembers
            .where((e) => e.isNotEmpty)
            .map((e) => int.tryParse(e))
            .where((e) => e != null)
            .map((e) => e!)
            .toList();

        if (parsedMembers.isEmpty) {
          return;
        }

        uids.addAll(parsedMembers);

        for (int uid in parsedMembers) {
          if (groupedEvents.containsKey(uid)) {
            groupedEvents[uid]!.add(event);
          } else {
            groupedEvents[uid] = [event];
          }
        }
      });
    } catch (e, stackTrace) {
      ALogger.e(e);
    }

    // 使用 HashSet 进行快速查找
    for (int uid in uids) {
      if (!groupedEvents.containsKey(uid)) {
        groupedEvents[uid] = [];
      }
    }

    var titles = groupedEvents.values
        .expand((list) => list)
        .map((event) => event.title)
        .toList();
    // ALogger.i("groupEventsByAttendees leave: groupedEvents= ${titles}");
    return groupedEvents;
  }
}

class MemberCompletionItem {
  String? name;
  int? color;
  String? progress;
}

class CalendarItem {
  num? finish;
  String? title;
  String? subtitle;
  String? subtitleColor;
  String? name;
  int? color;
  int itemType = 0;
  String itemTitle = "";

  EventDTO? eventDTO;
}
